package name.manana.jarina;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import name.manana.jarina.CacheJars.OneJarEntry;
import org.apache.log4j.Logger;



/**
 * Main executable class.
 * 
 * @author Jan Marcis
 *
 */
public class MainApp {

	private static final Logger log = Logger.getLogger(MainApp.class);
    
    //public static final String MAVEN_REPO = "c:\\users\\honza\\.m2\\repository";
    public static String MAVEN_REPO;
    
    // public static final String PROJECT_DIR = "C:\\source\\Jarin\\TEST_DIRECTORY";
    public static String PROJECT_DIR;
    
    public static String javaSourceDirectory;
    
    /**
     * Application start point. args should be: projectDir, mavenDir 
     * @param args
     */
    public static void main(String[] args) {
    	log.info("START APPLICATION...");
    	if(args == null || args.length <2) {
    		System.exit(0);
    	}
    	PROJECT_DIR = args[0];
    	MAVEN_REPO = args[1];
        findProjectSourceDir(PROJECT_DIR);
        processingSources(initCache());
    }
    
    private static CacheJars initCache() {
    	CacheJars cache = null;
    	if(!CacheJars.cacheFile.exists()) {
    		cache = new CacheJars(MAVEN_REPO);
    	} else {
    		cache = CacheJars.loadFromDisk();
    	}
    	return cache;
    }
    
    private static void findProjectSourceDir(String projectDir) {
    	log.debug("checking project files, backuping, checking source directory.");
        FileUtil fileUtil = FileUtil.getInstance(projectDir);
        try {
        	fileUtil.checkProjectFiles(projectDir);
        	fileUtil.backupFile(new File(projectDir + "/.classpath"), new File(projectDir + "/.classpath.bak"));
            javaSourceDirectory = fileUtil.getProjectSourceDirectory(projectDir);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    
    private static void recurseFinder(Set<OneJarEntry> result, Set<String> imports, CacheJars cache) {
        for(String jarImp: imports) {
            OneJarEntry matchingJar = cache.findJar(jarImp);
            if (matchingJar != null && !result.contains(matchingJar)) {
                log.info("Need this jar: "+ matchingJar);
                result.add(matchingJar);
                
                // for matching jar check imports from class, which srcImp has recerencing
                String sourceJarPath = CacheJars.makeSrcJarPath(matchingJar.getJarPath());
                if(new File(sourceJarPath).exists()) {
                	JarResources srcJar = new JarResources(sourceJarPath);
                	recurseFinder(result, srcJar.getAllImports(jarImp), cache);
                }
            }
        }
    }


    private static void processingSources(CacheJars cache)  {
        // for every source
        log.info("start reading java sources...");
        Set<OneJarEntry> result = new HashSet<OneJarEntry>();
        FileUtil fileUtil = FileUtil.getInstance();
        HashSet<File> vsechnyJavy = fileUtil.getAllFiles(javaSourceDirectory, ".java", new String[] {}, new String[] {});
        for (File java : vsechnyJavy) {
            //  check imports
            log.debug("processing java file: " + java.getName());
            JarResources tridaSource = new JarResources(java.getPath(),"name.manana.TODOCLASS");
            Set<String> oneJavaSrcImps = tridaSource.getAllImports(); 
            recurseFinder(result, oneJavaSrcImps, cache);
        }
        // save needed jars
        fileUtil.completeClasspath(result);
    }

    

}
